package edu.mse.camel.client.playback.events;

import java.util.ArrayList;
import java.util.List;
import java.util.Observable;

import edu.mse.camel.client.core.events.model.ModelRewind;
import edu.mse.camel.client.core.events.model.ModelUpdateEvent2;
import edu.mse.camel.client.core.events.model.PlaybackPost;
import edu.mse.camel.client.eventbus.pubsub.EventManager;
import edu.mse.camel.client.events.peer.ReceiveGenericPeerEvent;
import edu.mse.camel.client.events.peer.ViewportChangeEvent;

public class ReceiveGenericPeerEventList extends Observable implements IReceiveGenericPeerEventList{

	private List<List<ReceiveGenericPeerEvent>> eventList;
//	private List<ReceiveGenericPeerEvent> events;
//	private ReceiveGenericPeerEvent current;
	private int currentIndex;
	
	public int getCurrentIndex() {
		return currentIndex;
	}

	public void setCurrentIndex(int currentIndex) {
		this.currentIndex = currentIndex;
	}

	private static ReceiveGenericPeerEventList INSTANCE = new ReceiveGenericPeerEventList();
	
	public static ReceiveGenericPeerEventList getInstance(){
		return INSTANCE;
	}
	
	public ReceiveGenericPeerEventList() {
//		events = new ArrayList<ReceiveGenericPeerEvent>();
		eventList = new ArrayList<List<ReceiveGenericPeerEvent>>();
//		current = null;
		currentIndex = -1;
	}

	@Override
	public void addEvent(ReceiveGenericPeerEvent event, int index) {
		List<ReceiveGenericPeerEvent> events = new ArrayList<ReceiveGenericPeerEvent>();

		if(index < eventList.size())
			events = eventList.get(index);

		events.add(event);
		
		if(index < eventList.size())
			eventList.set(index, events);
		else
			eventList.add(index, events);
	}

	@Override
	public List<ReceiveGenericPeerEvent> getEvents(int index) {
		return eventList.get(index);
	}

	public List<List<ReceiveGenericPeerEvent>> getEventList(){
		return eventList;
	}
	
//	@Override
//	public void nextEvent(String timestamp) {
//		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");		
//		Date tempDate = new Date();
//		
//		try {
//			tempDate = sdf.parse(timestamp);
//		} catch (ParseException e) {
//			e.printStackTrace();
//		}
//		
//		for(ReceiveGenericPeerEvent event:events)
//		{
//			if(event.getOrginalTime().after(tempDate))
//				break;
//			if(event.getOrginalTime().before(current.getOrginalTime())){
//				if ( event.getDataType().equals(ModelUpdateEvent2.class.getCanonicalName())) {
//					ModelUpdateEvent2 me = event.readObject(ModelUpdateEvent2.class);
//					EventManager.getInstance().dispatchEventAsynchronous(me, false);
//				}else if ( event.getDataType().equals(ViewportChangeEvent.class.getCanonicalName())) {
//					ViewportChangeEvent vp = event.readObject(ViewportChangeEvent.class);				
//					vp.userID = event.getUserID(); //IMPORTANT
//					EventManager.getInstance().dispatchEventAsynchronous(vp, false);
//				}				
//			}				
//		}
//	}

	@Override
	public void nextEvent(int index) {
//		currentIndex = index;
//		List<ReceiveGenericPeerEvent> events = eventList.get(index);
//		for(ReceiveGenericPeerEvent event:events){
//			publish(event);
//		}
		jumpEvent(index);
	}

	public void previousEvent() {

//		int size;
//		size = eventList.get(currentIndex).size();

		List<ReceiveGenericPeerEvent> events;
		events = eventList.get(currentIndex);
		for(ReceiveGenericPeerEvent event:events){
			if (event.getDataType().equals(ModelUpdateEvent2.class.getCanonicalName())) {
				ModelRewind mrEvent = new ModelRewind();
				EventManager.getInstance().dispatchEventSynchronous(mrEvent, true);				
			}
		}
		

		//if(size>0){
		//	ModelRewind event = new ModelRewind();
		//	EventManager.getInstance().dispatchEventSynchronous(event, true);
		//}
		
		currentIndex--;
		
		this.setChanged();
		notifyObservers(this);

	}
	@Override
	public void jumpEvent(int index) {
	
		if(currentIndex > index){
			currentIndex = -1;
			//refresh to poster board
		}
		
		List<ReceiveGenericPeerEvent> events;
		while(currentIndex < index){
			currentIndex ++;
			events = eventList.get(currentIndex);
			for(ReceiveGenericPeerEvent event:events){
				publish(event);
			}
		}
	
		PlaybackPost ppEvent = new PlaybackPost();
		EventManager.getInstance().dispatchEventAsynchronous(ppEvent, false);
		
		this.setChanged();
		notifyObservers(this);
	}

	private void publish(ReceiveGenericPeerEvent event){
		if (event.getDataType().equals(ModelUpdateEvent2.class.getCanonicalName())) {
			ModelUpdateEvent2 me = event.readObject(ModelUpdateEvent2.class);
			EventManager.getInstance().dispatchEventAsynchronous(me, false);
		}else if ( event.getDataType().equals(ViewportChangeEvent.class.getCanonicalName())) {
			ViewportChangeEvent vp = event.readObject(ViewportChangeEvent.class);				
			vp.userID = event.getUserID(); //IMPORTANT
			EventManager.getInstance().dispatchEventAsynchronous(vp, false);
		}
	}
}
